﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Controls.Primitives;

namespace Greg.WPF.Controls
{
    /// <summary>
    /// Interaction logic for UserControl1.xaml
    /// </summary>
    public partial class RotatingKnob : UserControl
    {
        /// <summary>
        /// Event to handle turning events
        /// </summary>
        public event KnobStartedEventHandler KnobStarted;
        public delegate void KnobStartedEventHandler(Object sender, KnobTurnedEventArgs e);

        public event KnobCompletedEventHandler KnobCompleted;
        public delegate void KnobCompletedEventHandler(Object sender, KnobTurnedEventArgs e);

        public event KnobTurnedEventHandler KnobTurned;
        public delegate void KnobTurnedEventHandler(Object sender, KnobTurnedEventArgs e);

        public class KnobTurnedEventArgs : EventArgs
        {
            public double Value { get; set; }
            public KnobTurnedEventArgs(double value) { this.Value = value; }
        }
       
        /// <summary>
        /// State and image data for knob.
        /// </summary>
        
        public double InitialRotation { get; set;}
        public String KnobNormalImage { get { return knobNormalImage.ToString();}  set { knobNormalImage = new BitmapImage(new Uri(value, UriKind.RelativeOrAbsolute)); } }
        public String KnobDepressedImage { get { return knobDepressedImage.ToString(); } set { knobDepressedImage = new BitmapImage(new Uri(value, UriKind.RelativeOrAbsolute)); } }
        protected RotateTransform KnobRotateTransform;
        BitmapImage knobNormalImage;
        BitmapImage knobDepressedImage;

        public double Value { get; set; }
        public double ValuePreview { get; set; }
        public double ValueMinimum { get; set; }
        public double ValueMaximum { get; set; }
        public double KnobSensitivityAngle { get; set; }
        public double KnobSensitivityValue { get; set; }
        
    
        public RotatingKnob()
        {
            KnobSensitivityAngle = 1;
            KnobSensitivityValue = 3;
            Value = 0;
            ValuePreview = 0;
            InitializeComponent();               
        }

        protected void knob_Loaded(object sender, RoutedEventArgs e)
        {
            if (knobNormalImage == null) knobNormalImage = new BitmapImage(new Uri("knob4a.png", UriKind.RelativeOrAbsolute));
            if (knobDepressedImage == null) knobDepressedImage = new BitmapImage(new Uri("knob4b.png", UriKind.RelativeOrAbsolute));
            knob.Source = knobNormalImage;
            KnobRotateTransform = new RotateTransform(InitialRotation);
            knob.RenderTransform = KnobRotateTransform;
            KnobRotateTransform.CenterX = knob.ActualHeight / 2;
            KnobRotateTransform.CenterY = knob.ActualWidth / 2;
            knob.RenderTransform = KnobRotateTransform;          
        }
        
        private void myThumb_DragStarted(object sender, DragStartedEventArgs e)
        {           
            knob.Source = knobDepressedImage;
            KnobTurnedEventArgs kte = new KnobTurnedEventArgs(0);
            if (KnobStarted != null) KnobStarted(this, kte);
        }

        private void myThumb_DragCompleted(object sender, DragCompletedEventArgs e)
        {
            knob.Source = knobNormalImage;   
            InitialRotation = KnobRotateTransform.Angle;
            Value = ValuePreview;
            KnobTurnedEventArgs kte = new KnobTurnedEventArgs(Value);
            if (KnobCompleted != null) KnobCompleted(this, kte);
        }

        protected void myThumb_DragDelta(object sender, DragDeltaEventArgs e)
        {
            KnobRotateTransform.Angle = (e.VerticalChange) * KnobSensitivityAngle + InitialRotation;
            ValuePreview = Value + e.VerticalChange * KnobSensitivityValue;
            KnobTurnedEventArgs kte = new KnobTurnedEventArgs(ValuePreview);
            if (KnobTurned != null) KnobTurned(this, kte);                  
        }
    }
}
